﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using AutoMapper;
using Company.Project.Domain.Model.DTO;
using Company.Project.Web.Admin.Areas.Admin.Lib;
using Company.Project.Web.Admin.Areas.Admin.Lib.Authorization;
using Z.Nlayer.Utility;
using Z.Nlayer.Utility.ImageUpload;
using Z.Nlayer.Utility.MVC;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.DataAnnotations.Internal;
using Microsoft.AspNetCore.Routing;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using UEditorNetCore;
using Z.Nlayer.Domain.Base;
using Z.Nlayer.Infrastructure.Cache;
using Company.Project.Infrastructure.IoC.CoreNative;

namespace Company.Project.Web.Admin
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
                {
                    options.LoginPath = "/Admin/Home/Login";
                    options.LogoutPath = "/Admin/Home/LoginOut";
                    options.AccessDeniedPath = "/Admin/Home/LoginOut?msg=登录已过期,请重新登录!";
                    //集群部署时,秘钥存放位置物理,需要注意的是，当单台服务器产生加密文件后，其他服务器均采用同样名称的key文件即可实现集群下Provider唯一
                    options.DataProtectionProvider = DataProtectionProvider.Create(new DirectoryInfo(ReadConfig.ReadAppSetting("DPRoot")),
                        configure =>
                        {
                            configure.SetApplicationName("Company.Project.Web.Admin");
                        });
                });
            services.AddAuthorization(options =>
            {
                options.AddPolicy("Admin",
                    policy => policy.Requirements.Add(new AdminAuthorizationRequirement()));
            });
            //启动日志记录
            services.UseLocalLog();
            //对基础设施层全局依赖注入
            services.RegServices();
            //对基础设施的依赖注入
            //对本地类型依赖注入
            services.RegLocalServices();
            //初始化automapper
            services.MapperInitialize();
            //采用redis作为cache依赖
            services.AddDistributedRedisCache(option =>
            {
                option.Configuration = ReadConfig.ReadAppSetting("RedisConn");
                option.InstanceName = "Company.Project.Cache";
                
            });
            services.AddSession();
            services.AddUEditorService(Directory.GetCurrentDirectory() + "/wwwroot/Areas/Admin/assets/js/ueditor/config.json").Remove("uploadimage").Add("uploadimage", UeditorUploadHandle.Upload);//重写uedotor上传图片
            services.AddMvc(optons =>
            {
                optons.ModelMetadataDetailsProviders.Add(new CustomerModelMetadataProvider());//避免视图模型属性出现null的情况
            }).AddJsonOptions(
                options =>
                {
                    options.SerializerSettings.ReferenceLoopHandling =
                        Newtonsoft.Json.ReferenceLoopHandling.Ignore; //避免循环引用
                    options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";//时间格式
                }
            );
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseBrowserLink();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }
            app.UseStaticFiles();
            app.UseAuthentication();
            app.UseStaticHttpContext();//模拟HttpContext.Current
            app.UseSession();
            app.UseMvc(routes =>
            {
                routes.MapRoute(name: "areaRoute",
                    template: "{area:exists}/{controller}/{action}/{id?}",
                    defaults: new { controller = "Home", action = "Index" });
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action}/{id?}",
                    defaults: new { controller = "Home", action = "Index" });
            });
        }
    }
}
